package models

import (
	fmt "fmt"
	time "time"

	github_com_go_courier_sqlx_v2 "github.com/go-courier/sqlx/v2"
	github_com_go_courier_sqlx_v2_builder "github.com/go-courier/sqlx/v2/builder"
	github_com_go_courier_sqlx_v2_datatypes "github.com/go-courier/sqlx/v2/datatypes"
)

func (DeviceAdditional) PrimaryKey() []string {
	return []string{
		"ID",
	}
}

func (DeviceAdditional) Comments() map[string]string {
	return map[string]string{
		"CreatedAt":          "创建时间",
		"DeletedAt":          "删除时间",
		"DeviceAdditionalID": "额外信息ID",
		"DeviceID":           "设备ID",
		"ID":                 "自增ID",
		"TagKey":             "标签键",
		"TagValue":           "标签值",
		"UpdatedAt":          "更新时间",
	}
}

var DeviceAdditionalTable *github_com_go_courier_sqlx_v2_builder.Table

func init() {
	DeviceAdditionalTable = DBVideoHub.Register(&DeviceAdditional{})
}

type DeviceAdditionalIterator struct {
}

func (DeviceAdditionalIterator) New() interface{} {
	return &DeviceAdditional{}
}

func (DeviceAdditionalIterator) Resolve(v interface{}) *DeviceAdditional {
	return v.(*DeviceAdditional)
}

func (DeviceAdditional) TableName() string {
	return "t_device_additional"
}

func (DeviceAdditional) TableDescription() []string {
	return []string{
		"设备额外信息表",
	}
}

func (DeviceAdditional) ColDescriptions() map[string][]string {
	return map[string][]string{
		"CreatedAt": []string{
			"创建时间",
		},
		"DeletedAt": []string{
			"删除时间",
		},
		"DeviceAdditionalID": []string{
			"额外信息ID",
		},
		"DeviceID": []string{
			"设备ID",
		},
		"ID": []string{
			"自增ID",
		},
		"TagKey": []string{
			"标签键",
		},
		"TagValue": []string{
			"标签值",
		},
		"UpdatedAt": []string{
			"更新时间",
		},
	}
}

func (DeviceAdditional) FieldKeyID() string {
	return "ID"
}

func (m *DeviceAdditional) FieldID() *github_com_go_courier_sqlx_v2_builder.Column {
	return DeviceAdditionalTable.F(m.FieldKeyID())
}

func (DeviceAdditional) FieldKeyDeviceAdditionalID() string {
	return "DeviceAdditionalID"
}

func (m *DeviceAdditional) FieldDeviceAdditionalID() *github_com_go_courier_sqlx_v2_builder.Column {
	return DeviceAdditionalTable.F(m.FieldKeyDeviceAdditionalID())
}

func (DeviceAdditional) FieldKeyDeviceID() string {
	return "DeviceID"
}

func (m *DeviceAdditional) FieldDeviceID() *github_com_go_courier_sqlx_v2_builder.Column {
	return DeviceAdditionalTable.F(m.FieldKeyDeviceID())
}

func (DeviceAdditional) FieldKeyTagKey() string {
	return "TagKey"
}

func (m *DeviceAdditional) FieldTagKey() *github_com_go_courier_sqlx_v2_builder.Column {
	return DeviceAdditionalTable.F(m.FieldKeyTagKey())
}

func (DeviceAdditional) FieldKeyTagValue() string {
	return "TagValue"
}

func (m *DeviceAdditional) FieldTagValue() *github_com_go_courier_sqlx_v2_builder.Column {
	return DeviceAdditionalTable.F(m.FieldKeyTagValue())
}

func (DeviceAdditional) FieldKeyCreatedAt() string {
	return "CreatedAt"
}

func (m *DeviceAdditional) FieldCreatedAt() *github_com_go_courier_sqlx_v2_builder.Column {
	return DeviceAdditionalTable.F(m.FieldKeyCreatedAt())
}

func (DeviceAdditional) FieldKeyUpdatedAt() string {
	return "UpdatedAt"
}

func (m *DeviceAdditional) FieldUpdatedAt() *github_com_go_courier_sqlx_v2_builder.Column {
	return DeviceAdditionalTable.F(m.FieldKeyUpdatedAt())
}

func (DeviceAdditional) FieldKeyDeletedAt() string {
	return "DeletedAt"
}

func (m *DeviceAdditional) FieldDeletedAt() *github_com_go_courier_sqlx_v2_builder.Column {
	return DeviceAdditionalTable.F(m.FieldKeyDeletedAt())
}

func (DeviceAdditional) ColRelations() map[string][]string {
	return map[string][]string{
		"DeviceAdditionalID": []string{
			"DeviceAdditional",
			"DeviceAdditionalID",
		},
		"DeviceID": []string{
			"Device",
			"DeviceID",
		},
	}
}

func (m *DeviceAdditional) IndexFieldNames() []string {
	return []string{
		"ID",
	}
}

func (m *DeviceAdditional) ConditionByStruct(db github_com_go_courier_sqlx_v2.DBExecutor) github_com_go_courier_sqlx_v2_builder.SqlCondition {
	table := db.T(m)
	fieldValues := github_com_go_courier_sqlx_v2_builder.FieldValuesFromStructByNonZero(m)

	conditions := make([]github_com_go_courier_sqlx_v2_builder.SqlCondition, 0)

	for _, fieldName := range m.IndexFieldNames() {
		if v, exists := fieldValues[fieldName]; exists {
			conditions = append(conditions, table.F(fieldName).Eq(v))
			delete(fieldValues, fieldName)
		}
	}

	if len(conditions) == 0 {
		panic(fmt.Errorf("at least one of field for indexes has value"))
	}

	for fieldName, v := range fieldValues {
		conditions = append(conditions, table.F(fieldName).Eq(v))
	}

	condition := github_com_go_courier_sqlx_v2_builder.And(conditions...)

	condition = github_com_go_courier_sqlx_v2_builder.And(condition, table.F("DeletedAt").Eq(0))
	return condition
}

func (m *DeviceAdditional) Create(db github_com_go_courier_sqlx_v2.DBExecutor) error {

	if m.CreatedAt.IsZero() {
		m.CreatedAt = github_com_go_courier_sqlx_v2_datatypes.Timestamp(time.Now())
	}

	if m.UpdatedAt.IsZero() {
		m.UpdatedAt = github_com_go_courier_sqlx_v2_datatypes.Timestamp(time.Now())
	}

	_, err := db.ExecExpr(github_com_go_courier_sqlx_v2.InsertToDB(db, m, nil))
	return err

}

func (m *DeviceAdditional) DeleteByStruct(db github_com_go_courier_sqlx_v2.DBExecutor) error {

	_, err := db.ExecExpr(
		github_com_go_courier_sqlx_v2_builder.Delete().
			From(
				db.T(m),
				github_com_go_courier_sqlx_v2_builder.Where(m.ConditionByStruct(db)),
				github_com_go_courier_sqlx_v2_builder.Comment("DeviceAdditional.DeleteByStruct"),
			),
	)

	return err
}

func (m *DeviceAdditional) FetchByID(db github_com_go_courier_sqlx_v2.DBExecutor) error {

	table := db.T(m)

	err := db.QueryExprAndScan(
		github_com_go_courier_sqlx_v2_builder.Select(nil).
			From(
				db.T(m),
				github_com_go_courier_sqlx_v2_builder.Where(github_com_go_courier_sqlx_v2_builder.And(
					table.F("ID").Eq(m.ID),
					table.F("DeletedAt").Eq(m.DeletedAt),
				)),
				github_com_go_courier_sqlx_v2_builder.Comment("DeviceAdditional.FetchByID"),
			),
		m,
	)

	return err
}

func (m *DeviceAdditional) UpdateByIDWithMap(db github_com_go_courier_sqlx_v2.DBExecutor, fieldValues github_com_go_courier_sqlx_v2_builder.FieldValues) error {

	if _, ok := fieldValues["UpdatedAt"]; !ok {
		fieldValues["UpdatedAt"] = github_com_go_courier_sqlx_v2_datatypes.Timestamp(time.Now())
	}

	table := db.T(m)

	result, err := db.ExecExpr(
		github_com_go_courier_sqlx_v2_builder.Update(db.T(m)).
			Where(
				github_com_go_courier_sqlx_v2_builder.And(
					table.F("ID").Eq(m.ID),
					table.F("DeletedAt").Eq(m.DeletedAt),
				),
				github_com_go_courier_sqlx_v2_builder.Comment("DeviceAdditional.UpdateByIDWithMap"),
			).
			Set(table.AssignmentsByFieldValues(fieldValues)...),
	)

	if err != nil {
		return err
	}

	rowsAffected, _ := result.RowsAffected()
	if rowsAffected == 0 {
		return m.FetchByID(db)
	}

	return nil

}

func (m *DeviceAdditional) UpdateByIDWithStruct(db github_com_go_courier_sqlx_v2.DBExecutor, zeroFields ...string) error {

	fieldValues := github_com_go_courier_sqlx_v2_builder.FieldValuesFromStructByNonZero(m, zeroFields...)
	return m.UpdateByIDWithMap(db, fieldValues)

}

func (m *DeviceAdditional) FetchByIDForUpdate(db github_com_go_courier_sqlx_v2.DBExecutor) error {

	table := db.T(m)

	err := db.QueryExprAndScan(
		github_com_go_courier_sqlx_v2_builder.Select(nil).
			From(
				db.T(m),
				github_com_go_courier_sqlx_v2_builder.Where(github_com_go_courier_sqlx_v2_builder.And(
					table.F("ID").Eq(m.ID),
					table.F("DeletedAt").Eq(m.DeletedAt),
				)),
				github_com_go_courier_sqlx_v2_builder.ForUpdate(),
				github_com_go_courier_sqlx_v2_builder.Comment("DeviceAdditional.FetchByIDForUpdate"),
			),
		m,
	)

	return err
}

func (m *DeviceAdditional) DeleteByID(db github_com_go_courier_sqlx_v2.DBExecutor) error {

	table := db.T(m)

	_, err := db.ExecExpr(
		github_com_go_courier_sqlx_v2_builder.Delete().
			From(db.T(m),
				github_com_go_courier_sqlx_v2_builder.Where(github_com_go_courier_sqlx_v2_builder.And(
					table.F("ID").Eq(m.ID),
					table.F("DeletedAt").Eq(m.DeletedAt),
				)),
				github_com_go_courier_sqlx_v2_builder.Comment("DeviceAdditional.DeleteByID"),
			))

	return err
}

func (m *DeviceAdditional) SoftDeleteByID(db github_com_go_courier_sqlx_v2.DBExecutor) error {

	table := db.T(m)

	fieldValues := github_com_go_courier_sqlx_v2_builder.FieldValues{}
	if _, ok := fieldValues["DeletedAt"]; !ok {
		fieldValues["DeletedAt"] = github_com_go_courier_sqlx_v2_datatypes.Timestamp(time.Now())
	}

	if _, ok := fieldValues["UpdatedAt"]; !ok {
		fieldValues["UpdatedAt"] = github_com_go_courier_sqlx_v2_datatypes.Timestamp(time.Now())
	}

	_, err := db.ExecExpr(
		github_com_go_courier_sqlx_v2_builder.Update(db.T(m)).
			Where(
				github_com_go_courier_sqlx_v2_builder.And(
					table.F("ID").Eq(m.ID),
					table.F("DeletedAt").Eq(m.DeletedAt),
				),
				github_com_go_courier_sqlx_v2_builder.Comment("DeviceAdditional.SoftDeleteByID"),
			).
			Set(table.AssignmentsByFieldValues(fieldValues)...),
	)

	return err

}

func (m *DeviceAdditional) List(db github_com_go_courier_sqlx_v2.DBExecutor, condition github_com_go_courier_sqlx_v2_builder.SqlCondition, additions ...github_com_go_courier_sqlx_v2_builder.Addition) ([]DeviceAdditional, error) {

	list := make([]DeviceAdditional, 0)

	table := db.T(m)
	_ = table

	condition = github_com_go_courier_sqlx_v2_builder.And(condition, table.F("DeletedAt").Eq(0))

	finalAdditions := []github_com_go_courier_sqlx_v2_builder.Addition{
		github_com_go_courier_sqlx_v2_builder.Where(condition),
		github_com_go_courier_sqlx_v2_builder.Comment("DeviceAdditional.List"),
	}

	if len(additions) > 0 {
		finalAdditions = append(finalAdditions, additions...)
	}

	err := db.QueryExprAndScan(
		github_com_go_courier_sqlx_v2_builder.Select(nil).
			From(db.T(m), finalAdditions...),
		&list,
	)

	return list, err

}

func (m *DeviceAdditional) Count(db github_com_go_courier_sqlx_v2.DBExecutor, condition github_com_go_courier_sqlx_v2_builder.SqlCondition, additions ...github_com_go_courier_sqlx_v2_builder.Addition) (int, error) {

	count := -1

	table := db.T(m)
	_ = table

	condition = github_com_go_courier_sqlx_v2_builder.And(condition, table.F("DeletedAt").Eq(0))

	finalAdditions := []github_com_go_courier_sqlx_v2_builder.Addition{
		github_com_go_courier_sqlx_v2_builder.Where(condition),
		github_com_go_courier_sqlx_v2_builder.Comment("DeviceAdditional.Count"),
	}

	if len(additions) > 0 {
		finalAdditions = append(finalAdditions, additions...)
	}

	err := db.QueryExprAndScan(
		github_com_go_courier_sqlx_v2_builder.Select(
			github_com_go_courier_sqlx_v2_builder.Count(),
		).
			From(db.T(m), finalAdditions...),
		&count,
	)

	return count, err

}

func (m *DeviceAdditional) BatchFetchByIDList(db github_com_go_courier_sqlx_v2.DBExecutor, values []uint64) ([]DeviceAdditional, error) {

	if len(values) == 0 {
		return nil, nil
	}

	table := db.T(m)

	condition := table.F("ID").In(values)

	return m.List(db, condition)

}
